﻿using Flurl.Http;
using Newtonsoft.Json.Linq;
using Pay.Core;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Pay.Service {
    public class EaseMobApi {
        private string _clientId;
        private string _clientSecret;
        private string _token;
        private string _urlFormat = "https://a1.easemob.com/{0}/{1}/";
        private ILogHelper _log;

        public EaseMobApi(string appId, string clientId, string clientSecret) {
            var arr = appId.Split('#');
            _urlFormat = string.Format(_urlFormat, arr[0], arr[1]);
            _urlFormat += "{0}";
            _clientId = clientId;
            _clientSecret = clientSecret;
            _log = IocHelper.Get<ILogHelper>("ui_error");
            _token = GetToken().Result;
        }

        private async Task<string> GetToken() {
            var token = CacheHelper.Get<string>(_clientId);
            if (string.IsNullOrEmpty(token)) {
                try {
                    string url = string.Format(_urlFormat, "token");
                    var result = await url.PostJsonAsync(new {
                        grant_type = "client_credentials", client_id = _clientId, client_secret = _clientSecret
                    }).ReceiveString();
                    JObject jo = JObject.Parse(result);
                    int expire = jo.GetJsonValue<int>("expires_in");
                    string access_token = jo.GetValue("access_token").ToString();
                    CacheHelper.Set(_clientId, access_token, expire);

                    return access_token;
                } catch (Exception ex) {
                    if (ex is FlurlHttpException) {
                        var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                        _log.Error(error.error + ":" + error.error_description);
                    }
                }
                return "";
            }
            return token;
        }

        public async Task<string> CreateUser(long user_id, string password, string nickName) {
            try {
                string url = string.Format(_urlFormat, "users");
                var result = await url.WithOAuthBearerToken(_token).PostJsonAsync(new {
                    username = user_id.ToString(), password = password, nickname = nickName
                }).ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> GetUser(long user_id) {
            try {
                string url = string.Format(_urlFormat, "users/" + user_id);
                var result = await url.WithOAuthBearerToken(_token).GetAsync().ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }
        public async Task<string> GetUserStatus(long user_id) {
            try {
                string url = string.Format(_urlFormat, "users/" + user_id + "/status");
                var result = await url.WithOAuthBearerToken(_token).GetAsync().ReceiveString();
                JObject jo = JObject.Parse(result);
                string stliu = jo.GetValue("data").GetJsonValue<string>("stliu");
                return stliu;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> ResetPwd(long user_id, string newpassword) {
            try {
                string url = string.Format(_urlFormat, "users/" + user_id + "/password");
                var result = await url.WithOAuthBearerToken(_token).PutJsonAsync(new {
                    newpassword = newpassword
                }).ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> EditNickName(long user_id, string nickName) {
            try {
                string url = string.Format(_urlFormat, "users/" + user_id);
                var result = await url.WithOAuthBearerToken(_token).PutJsonAsync(new {
                    nickname = nickName
                }).ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> DeleteUser(long user_id) {
            try {
                string url = string.Format(_urlFormat, "users/" + user_id);
                var result = await url.WithOAuthBearerToken(_token).DeleteAsync().ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<long> CreateGroup(long user_id, string name) {
            try {
                string url = string.Format(_urlFormat, "chatgroups");
                var result = await url.WithOAuthBearerToken(_token).PostJsonAsync(new {
                    groupname = name, desc = name, @public = false, maxusers = 2000,
                    approval = false, owner = user_id
                }).ReceiveString();
                JObject jo = JObject.Parse(result);
                JToken data = jo.GetValue("data");
                var groupid = data.GetJsonValue<long>("groupid");
                return groupid;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return 0;
        }

        public async Task<string> EditGroup(long group_id, string name, int maxusers) {
            try {
                string url = string.Format(_urlFormat, "chatgroups/" + group_id);
                var result = await url.WithOAuthBearerToken(_token).PutJsonAsync(new {
                    groupname = name, maxusers = maxusers
                }).ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> DeleteGroup(long group_id) {
            try {
                string url = string.Format(_urlFormat, "chatgroups/" + group_id);
                var result = await url.WithOAuthBearerToken(_token).DeleteAsync().ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> CreateGroupUser(long group_id, long user_id) {
            try {
                string url = string.Format(_urlFormat, "chatgroups/" + group_id + "/users/" + user_id);
                var result = await url.WithOAuthBearerToken(_token).PostAsync(new StringContent("")).ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var call = (ex as FlurlHttpException).Call;
                    if (call.HttpStatus.HasValue && (int)call.HttpStatus == 403) {
                        return group_id.ToString();
                    }
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }

        public async Task<string> DeleteGroupUser(long group_id, long user_id) {
            try {
                string url = string.Format(_urlFormat, "chatgroups/" + group_id + "/users/" + user_id);
                var result = await url.WithOAuthBearerToken(_token).DeleteAsync().ReceiveString();
                return result;
            } catch (Exception ex) {
                if (ex is FlurlHttpException) {
                    var error = await (ex as FlurlHttpException).GetResponseJsonAsync<easemob_error>();
                    _log.Error(error.error + ":" + error.error_description);
                }
            }
            return "";
        }
    }
    public class easemob_error {
        public string error { get; set; }
        public string error_description { get; set; }
    }
}
